﻿using System;
using System.IO;
using System.Windows;
using Sinacor.OMM.Util;
using System.Diagnostics;

namespace Sinacor.OMM.Deployment.Extractor
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Extrator : Window
    {
        #region [ Constructor ]

        public Extrator()
		{
			this.InitializeComponent();
            this.ResizeMode = ResizeMode.NoResize;
        }

        #endregion

        #region [ Events ]

        private void btnSearchDirectory_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog folderPicker = new System.Windows.Forms.FolderBrowserDialog();
            folderPicker.Description = "Selecione o diretório para a extração dos arquivos.";
            folderPicker.ShowDialog();

            if (folderPicker.SelectedPath != string.Empty)
            {
                txtDirectory.Text = folderPicker.SelectedPath;
                btnExtractDirectory.Visibility = Visibility.Visible;
            }
        }        

        private void ExtratorScreen_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (ShowExitConfirm())
                CloseMainWindow();
            else
                e.Cancel = true;
        }

        private void ExtratorScreen_ClosingEnd(object sender, System.ComponentModel.CancelEventArgs e) { }

        private void btnExtractDirectory_GotFocus(object sender, RoutedEventArgs e)
        {
            try
            {
                btnExtractDirectory.Visibility = Visibility.Hidden;
                btnSearchDirectory.IsEnabled = false;
                LblErroExtraindo.Visibility = Visibility.Hidden;
                loader01.Visibility = Visibility.Visible;
                LblExtraindo.Visibility = Visibility.Visible;                

                string directory = txtDirectory.Text;               

                Func<string, bool> extractDispatcher = new Func<string, bool>(ExtractFiles);
                extractDispatcher.BeginInvoke(directory, ExtractAsyncCallBack, extractDispatcher);                                
            }
            catch (Exception ex)
            {
                loader01.Visibility = Visibility.Hidden;
                LblExtraindo.Visibility = Visibility.Hidden;
                LblErroExtraindo.Visibility = Visibility.Visible;
                btnExtractDirectory.Visibility = Visibility.Hidden;
                btnSearchDirectory.IsEnabled = true;
            }
        }

        #endregion

        #region [ Methods ]

        private void ExtractAsyncCallBack(IAsyncResult ar)
        {
            try
            {
                Func<string, bool> extractDispatcher = (Func<string, bool>)ar.AsyncState;
                extractDispatcher.EndInvoke(ar);
            }
            catch (System.UnauthorizedAccessException ex)
            {
                EventLog.WriteEntry("Não foi possível extrair os arquivos do Setup. Verifique se não existe nenhum processo OMM em execução", ex.Message);
                this.Dispatcher.Invoke(
                   (Action)delegate()
                   {
                       loader01.Visibility = Visibility.Hidden;
                       LblExtraindo.Visibility = Visibility.Hidden;
                       LblErroExtraindo.Content = "Não foi possível extrair os arquivos. Verifique se não existe nenhum processo OMM em execução.";
                       LblErroExtraindo.Visibility = Visibility.Visible;
                       btnExtractDirectory.Visibility = Visibility.Hidden;
                       btnSearchDirectory.IsEnabled = true;
                   });
            }
            catch (System.IO.IOException ex)
            {
                EventLog.WriteEntry("Não foi possível extrair os arquivos do Setup. Verifique se existe permissão no diretório selecionado.", ex.Message);
                this.Dispatcher.Invoke(
                   (Action)delegate()
                   {
                       loader01.Visibility = Visibility.Hidden;
                       LblExtraindo.Visibility = Visibility.Hidden;
                       LblErroExtraindo.Content = "Não foi possível extrair os arquivos. Verifique se existe permissão no diretório selecionado.";
                       LblErroExtraindo.Visibility = Visibility.Visible;
                       btnExtractDirectory.Visibility = Visibility.Hidden;
                       btnSearchDirectory.IsEnabled = true;
                   });
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("Não foi possível extrair os arquivos do Setup.", ex.Message);
                this.Dispatcher.Invoke(
                   (Action)delegate()
                   {
                       loader01.Visibility = Visibility.Hidden;
                       LblExtraindo.Visibility = Visibility.Hidden;
                       LblErroExtraindo.Content = "Não foi possível extrair os arquivos.";
                       LblErroExtraindo.Visibility = Visibility.Visible;
                       btnExtractDirectory.Visibility = Visibility.Hidden;
                       btnSearchDirectory.IsEnabled = true;
                   });
            }
        }

        private bool ShowExitConfirm()
        {
            if (MessageBox.Show("Deseja realmente sair do Setup?", "Setup OMM", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
                return true;
            return false;
        }

        private bool ExtractFiles(string directory)
        {
            bool ret = false;

            try
            {
                string currentDirectory = Environment.CurrentDirectory;
                string copyDirectory = string.Empty;
                string destDirectory = string.Empty;

                if (Directory.Exists(currentDirectory + @"\OrderMessageManager"))
                {
                    copyDirectory = currentDirectory + @"\OrderMessageManager";
                    destDirectory = directory + @"\OrderMessageManager";
                }
                else if (Directory.Exists(currentDirectory + @"\OMM"))
                {
                    copyDirectory = currentDirectory + @"\OMM";
                    destDirectory = directory + @"\OMM";
                }
                else
                {
                    MessageBox.Show("Não foi possível extrair os arquivos do Setup!", "Setup OMM", MessageBoxButton.OK, MessageBoxImage.Error);
                    CloseMainWindow();
                }

                CreateDirectory(destDirectory);
                CopyDirectory(copyDirectory, destDirectory);

                CreateShortcuts(destDirectory);
                RunSetup(destDirectory);
                CloseMainWindow();
                ret = true;
            }
            catch (Exception ex)
            {
                throw ex;                
            }
            return ret;
        }

        private void CloseMainWindow()
        {
            System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

        private void RunSetup(string destDirectory)
        {
            string setupExe = destDirectory + @"\" + "Setup.exe";

            if (System.IO.File.Exists(setupExe))
            {
                System.Diagnostics.Process process = new System.Diagnostics.Process();
                process.StartInfo.FileName = setupExe;
                process.StartInfo.WorkingDirectory = destDirectory;              
                process.Start();                
            }            
        }

        private void CreateDirectory(string destDirectory)
        {
            try
            {
                if (Directory.Exists(destDirectory))
                    Directory.Delete(destDirectory, true);

                Directory.CreateDirectory(destDirectory);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void CopyDirectory(string copyDirectory, string destDirectory)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(copyDirectory);
            FileInfo[] files = dirInfo.GetFiles("*", SearchOption.TopDirectoryOnly);
            foreach (FileInfo file in files)
            {
                file.IsReadOnly = false;
                file.CopyTo(destDirectory + @"\" + file.Name);
            }

            DirectoryInfo[] dirInfoChildren = dirInfo.GetDirectories();
            foreach (DirectoryInfo children in dirInfoChildren)
            {
                CreateDirectory(destDirectory + @"\" + children.Name);
                CopyDirectory(children.FullName, destDirectory + @"\" + children.Name);
            }
        }

        private void CreateShortcuts(string installPath)
        {
            Windows.CreateShortcut(string.Concat(Windows.GetFolderPath(Windows.SpecialFolder.Desktop), @"\Setup OMM.lnk"), string.Concat(installPath, @"\images\iconeOMM.ico"), string.Concat(installPath, @"\Setup.exe"));
            Windows.CreateShortcut(string.Concat(Windows.GetFolderPath(Windows.SpecialFolder.Desktop), @"\Configurador OMM.lnk"), string.Concat(installPath, @"\images\iconeOMM.ico"), string.Concat(installPath, @"\Configurator.exe"));
        }

        #endregion        
	}    
}
